//==================================================================================================
/*
  EVE - Expressive Vector Engine
  Copyright : EVE Project Contributors
  SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#include "test.hpp"

#include <eve/module/bessel.hpp>

TTS_CASE_TPL ( "Check eve::cyl_bessel_jn over real,  integral orders"
             , eve::test::scalar::ieee_reals
              )
<typename T>(tts::type<T>)
{
  auto constexpr N = 11;
  using a_t  = std::array<T, 16 >;
  using aN_t = std::array<a_t, N >;
  a_t re{-5.2999999999999998e+00, -4.5999999999999996e+00, -3.8999999999999999e+00, -3.2000000000000002e+00, -2.5000000000000000e+00, -1.7999999999999998e+00, -1.1000000000000005e+00, -4.0000000000000036e-01, 2.9999999999999982e-01, 1.0000000000000000e+00, 1.7000000000000002e+00, 2.3999999999999995e+00, 3.0999999999999988e+00, 3.7999999999999998e+00, 4.4999999999999991e+00, 5.2000000000000002e+00};
  aN_t resN16;
  //res are taken from octave 9.2.0 besselj outputs
  int p=0;
  resN16[p] = a_t{-7.5803111585584337e-02,-2.9613781657414129e-01,-4.0182601488763986e-01,-3.2018816965712299e-01,-4.8383776468197887e-02,3.3998641104255850e-01,7.1962201852751084e-01,9.6039822665956343e-01,9.7762624653829611e-01,7.6519768655796661e-01,3.9798485944610945e-01,2.5076832972440104e-03,-2.9206434765069744e-01,-4.0255641017856431e-01,-3.2054250898512165e-01,-1.1029043979098635e-01,};
  ++p; //1  1.000e+00
  resN16[p] = a_t{3.4596083380118614e-01,2.5655283609744456e-01,2.7244039620779734e-02,-2.6134324878050469e-01,-4.9709410246427410e-01,-5.8151695173116524e-01,-4.7090239486629315e-01,-1.9602657795531891e-01,1.4831881627310392e-01,4.4005058574493355e-01,5.7776523152902326e-01,5.2018526818193112e-01,3.0092113310105784e-01,1.2821002926731280e-02,-2.3106043192337039e-01,-3.4322300587192184e-01,};
  ++p; //2  2.000e+00
  resN16[p] = a_t{-5.4748146452599136e-02,1.8459310522742625e-01,3.8785471251800924e-01,4.8352770014493851e-01,4.4605905843961724e-01,3.0614353532540295e-01,1.3656415395665808e-01,1.9734663117030309e-02,1.1165861949063953e-02,1.1490348493190050e-01,2.8173894235274144e-01,4.3098004018769859e-01,4.8620701416750906e-01,4.0930430645579130e-01,2.1784898368584590e-01,-2.1718408621291267e-02,};
  ++p; //3  3.000e+00
  resN16[p] = a_t{-3.0464147798790381e-01,-4.1706857977346740e-01,-4.2504374476745610e-01,-3.4306637640066823e-01,-2.1660039103911358e-01,-9.8802015658619166e-02,-2.5694528612463328e-02,-1.3200532149839613e-03,5.5934304774884547e-04,1.9563353982668414e-02,8.5149926948015278e-02,1.9811479879756677e-01,3.2644275614734086e-01,4.1802563544778537e-01,4.2470397297745566e-01,3.2651653770169781e-01,};
  ++p; //4  4.000e+00
  resN16[p] = a_t{3.9962529134456570e-01,3.5940939012927037e-01,2.6605874097038468e-01,1.5972175560631446e-01,7.3781880054255233e-02,2.3196516869994299e-02,3.5878202931417628e-03,6.6135107729096981e-05,2.0999005912958305e-05,2.4766389641099548e-03,1.8790211581430169e-02,6.4306956806218285e-02,1.4561767514992499e-01,2.5073617056702785e-01,3.4842298028409507e-01,3.9846825981555795e-01,};
  ++p; //5  5.000e+00
  resN16[p] = a_t{-2.9856650894728981e-01,-2.0799122914700291e-01,-1.2071777517179463e-01,-5.6238012615117947e-02,-1.9501625134503219e-02,-4.2936148746888668e-03,-3.9870988311314481e-04,-2.6489395979775977e-06,6.3044326337710463e-07,2.4975773021123466e-04,3.2745981410678671e-03,1.6241723889827649e-02,4.9344792626659528e-02,1.0983998679858915e-01,1.9471465863871354e-01,2.8651155432223746e-01,};
  ++p; //6  6.000e+00
  resN16[p] = a_t{1.6370774440503777e-01,9.2745455842474969e-02,4.3474015880370753e-02,1.6022033815929034e-02,4.2246204837576452e-03,6.5689910049940010e-04,3.6815007886821227e-05,8.8382220342856326e-08,1.5769532945203197e-08,2.0938338002389290e-05,4.7213042485139177e-04,3.3668927347302495e-03,1.3559075258654116e-02,3.8316426271364439e-02,8.4276261135268454e-02,1.5251549849643697e-01,};
  ++p; //7  7.000e+00
  resN16[p] = a_t{-7.2092534988644749e-02,-3.3953438268149325e-02,-1.3048427537038451e-02,-3.8446141946159706e-03,-7.7655318753348508e-04,-8.5712461973804678e-05,-2.9083847430869274e-06,-2.5270123080882889e-09,3.3805443102187290e-10,1.5023258174368098e-06,5.8087210824311725e-05,5.9273978382361268e-04,3.1419503100661200e-03,1.1159254058351300e-02,3.0022037722002282e-02,6.5447288361847988e-02,};
  ++p; //8  8.000e+00
  resN16[p] = a_t{2.6725366885722017e-02,1.0591095408414348e-02,3.3664932269467642e-03,7.9815328551583993e-04,1.2407736642986879e-04,9.7533815190810586e-06,2.0079793428509813e-07,6.3210440233588182e-11,6.3405024842634843e-12,9.4223441726045045e-08,6.2348407605872882e-06,9.0756004240824634e-05,6.3037775454772259e-04,2.7966149962455919e-03,9.1256339998497978e-03,2.3688739400846145e-02,};
  ++p; //9  9.000e+00
  resN16[p] = a_t{-8.5878178739122978e-03,-2.8851544567701530e-03,-7.6282672735853297e-04,-1.4615223296322559e-04,-1.7541957617676030e-05,-9.8426264024908809e-07,-1.2312482878135401e-08,-1.4053012552418853e-12,1.0570147217965338e-13,5.2492501799118741e-09,5.9364339298043490e-07,1.2300244448551674e-05,1.1161229405115996e-04,6.1596697847225311e-04,2.4246609441303628e-03,7.4411405638324648e-03,};
  ++p; //10  1.000e+01
  resN16[p] = a_t{2.4408070256782010e-03,6.9863942242537325e-04,1.5424551470800298e-04,2.3953024902303902e-05,2.2247284173983809e-06,8.9244883409817240e-08,6.7905826620767734e-10,2.8116252296525914e-14,1.5858465157002424e-15,2.6306151236874540e-10,5.0795165087887817e-08,1.4958291233129357e-06,1.7693630265464491e-05,1.2112332283350109e-04,5.7300977667164331e-04,2.0690548585739106e-03,};
  using eve::spherical;
  auto h =  eve::half(eve::as<T>());
  for(int j=0; j <= 15; ++j)
  {
    auto c = re[j];
    auto fac = eve::sqrt(eve::pio_2(eve::as(c))*eve::rec(c));
    for(int i=0; i < N; ++i)
    {
      auto res = resN16[i][j];
      TTS_RELATIVE_EQUAL(eve::bessel_j(i, c), res, tts::prec<T>());
      TTS_RELATIVE_EQUAL(eve::bessel_j(-i, c), eve::sign_alternate(i)*res, tts::prec<T>());
      TTS_RELATIVE_EQUAL(eve::bessel_j[spherical](i, c), eve::bessel_j(i+h, c)*fac, tts::prec<T>());
      TTS_RELATIVE_EQUAL(eve::bessel_j[spherical](-i, c), eve::bessel_j(-i+h, c)*fac, tts::prec<T>());
    }
  }
};
